/**
 * 本示例模拟了一次向流中写入数据，并响应写入操作，获取写入数据输出到屏幕的过程
 * 其中，写入过程包括：
 *  1. 获取写入流的 writer
 *  2. 以流的方式编码数据
 *  3. 检查写入流准备状态，并写入
 *  4. 写入完成后关闭写入流
 * 读取过程包括：
 *  1. 在创建写入流时，定义 write 响应方法
 *  2. 在 write 方法中使用 chunk 构建 typeArray
 *  3. 解码 typeArray
 *  4. 创建元素并插入文档流
 */

const list = document.querySelector('ul');
let result = '';

const sendMessage = (message, writeStream) => {
  // 获取写入器
  const defaultWriter = writeStream.getWriter();
  const encoder = new TextEncoder();
  const encoded = encoder.encode(message, { stream: true }); // 流编码
  encoded.forEach(chunk => {
    defaultWriter.ready
      .then(() => {
        return defaultWriter.write(chunk); // 写入已编码数据
      })
      .then(() => {
        console.log('Chunk write to sink');
      })
      .catch(err => console.error('Chunk err: ', err))
  });
  // 关闭前，再次调用 ready 确保写入完成
  defaultWriter.ready
    .then(() => {
      defaultWriter.close();
    })
    .then(() => {
      console.log('All chunk writen')
    })
    .catch(err => console.error('Stream error: ', err));
}

const decoder = new TextDecoder('utf-8');
// 队列计数策略，用于创建写入流
// hiehWaterMark: 非负整数，定义了可以被包含到队列中的 chunk 总数
const queuingStrategy = new CountQueuingStrategy({ highWaterMark: 1 });
const writeStream = new WritableStream({
  write(chunk) {
    return new Promise(resolve => {
      const buffer = new ArrayBuffer(2);
      const view = new Uint16Array(buffer); // 构建视图对象
      view[0] = chunk;
      let decoded = decoder.decode(view, { stream: true });
      const listItem = document.createElement('li');
      listItem.textContent = 'Chunk decode: ' + decoded;
      list.appendChild(listItem);
      result += decoded;
      resolve();
    })
  },
  close() {
    // 当写入流关闭时
    const listItem = document.createElement('li');
    listItem.textContent = '[MESSAGE RECIVED ]' + result;
    list.appendChild(listItem);
  },
  abort(err) {
    console.error("Sink error:", err)
  }
}, queuingStrategy);

sendMessage('Hello world', writeStream);